﻿// SKNotes - a note taking and gathering tool
// Copyright (C) 2009  Stefan Kueng
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

namespace SKNotes.Utilities
{
    using System;
    using System.Runtime.InteropServices;
    using System.Windows;
    using System.Windows.Interop;
    using System.Windows.Media;

    [StructLayout(LayoutKind.Sequential)]
    public struct MARGINS
    {
        public int cxLeftWidth;
        public int cxRightWidth;
        public int cyTopHeight;
        public int cyBottomHeight;
    };

    public class GlassEffect
    {
        [DllImport("DwmApi.dll")]
        public static extern int DwmExtendFrameIntoClientArea(IntPtr hwnd, ref MARGINS pMarInset);

        [DllImport("dwmapi.dll", PreserveSig = false)]
        static extern bool DwmIsCompositionEnabled();

        public static readonly DependencyProperty GlassMarginProperty =
            DependencyProperty.RegisterAttached("GlassMargin",
                typeof(Thickness),
                typeof(GlassEffect),
                new FrameworkPropertyMetadata(OnGlassMarginChanged));

        public static void SetGlassMargin(DependencyObject element, Thickness value)
        {
            element.SetValue(GlassMarginProperty, value);
        }

        public static Thickness GetGlassMargin(DependencyObject element)
        {
            return (Thickness)element.GetValue(GlassMarginProperty);
        }

        public static void OnGlassMarginChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            Window wnd = (Window)obj;
            wnd.Loaded += new RoutedEventHandler(wnd_Loaded);
        }

        static void wnd_Loaded(object sender, RoutedEventArgs e)
        {
            Window wnd = (Window)sender;
            Brush originalBackground = wnd.Background;
            wnd.Background = Brushes.Transparent;
            try
            {
                IntPtr mainWindowPtr = new WindowInteropHelper(wnd).Handle;
                HwndSource mainWindowSrc = HwndSource.FromHwnd(mainWindowPtr);
                mainWindowSrc.CompositionTarget.BackgroundColor = Color.FromArgb(0, 0, 0, 0);

                MARGINS margins = new MARGINS();
                Thickness t = (Thickness)wnd.GetValue(GlassMarginProperty);
                margins.cxLeftWidth = (int)t.Left;
                margins.cxRightWidth = (int)t.Right;
                margins.cyTopHeight = (int)t.Top;
                margins.cyBottomHeight = (int)t.Bottom;

                DwmExtendFrameIntoClientArea(mainWindowSrc.Handle, ref margins);
            }
            catch (DllNotFoundException)
            {
                wnd.Background = originalBackground;
            }
        }

    }

}
